<?php
/**
 * The Router class, a holder for router objects.
 *
 * Routes are the way to tell the framework how to handle URLs. Although regular expressions
 * are used internally they are generated from the route instruction.
 * For these examples www.example.com will be used as the URL.
 * 
 * The most basic route is ''. This is set up by default to call Page->display() but can
 * be overridden by passing a class and method to the constructor.
 * 
 * A route needs to be a path with optional parameters. '/home' will match http://www.example.com/home,
 * '/home/admin' will match http://www.example.com/home/admin. Trailing slashes are optional.
 * 
 * Parameters are in the form '(param:type)' where 'param' is the name of the parameter that
 * will be made available by Request->getParam() and 'type' is the type of data to expect. Currently
 * only 'str' and 'int' are recognised for string and integer data. 
 */
class Router {
    /**
     * Array of Route objects.
     * @var array
     */
    protected $routes = array();
    
    /**
     * The constructor.
     * @param string $class
     * @param string $method
     */
    public function __construct($class = false, $method = false) {
        if(!$class) {
            $class = 'Page';
        }
        if(!$method) {
            $method = 'display';
        }
        $this->addRoute('', $class, $method);
    }
    
    /**
     * Add a new route.
     * @param string $route
     * @param string $class
     * @param string $method
     * @param int $id
     */
    public function addRoute($route, $class, $method, $id = false) {
        $routeobj = new Route($route, $class, $method);
        foreach($this->routes as $r) {
            if($r->getRoute() == $routeobj->getRoute()) {
                throw new Router_Exception("A route for '$route' already exists.");
            }
        }
        if($id) {
            if(isset($this->routes[$id])) {
                throw new Router_Exception("Route ID $id is already in use.");
            }
            $this->routes[$id] = $routeobj;
        } else {
            $this->routes[] = $routeobj;
        }
    }
    
    /**
     * Delete a route and return it.
     * @param int $id
     * @return Route
     */
    public function deleteRoute($id) {
        $route = $this->routes[$id];
        unset($this->routes[$id]);
        return $route;
    }
    
    /**
     * Work out which route to use by calling Route->checkRoute().
     * @param string $url
     * @return Route
     */
    public function route($url) {
        foreach($this->routes as $route) {
            if($route->checkRoute($url)) {
                return $route;
            }
        }
        return null;
    }
}
?>